///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#ifndef __Lod_Strategy_H__
#define __Lod_Strategy_H__

#include "OgrePrerequisites.h"

#include "OgreMesh.h"

#include "OgreMovableObject.h"
#include "OgreCamera.h"

namespace Ogre {

	
	
	
	class _OgreExport LodStrategy : public MemAlloc_SceneCtrl
    {
    protected:
        
        String mName;

        
        virtual Real getValueImpl(const MovableObject *movableObject, const Camera *camera) const = 0;

    public:
        
        LodStrategy(const String& name);

        
        virtual ~LodStrategy();

        
        virtual Real getBaseValue() const = 0;

        
        virtual Real transformBias(Real factor) const = 0;

        
        virtual Real transformUserValue(Real userValue) const;

        
        Real getValue(const MovableObject *movableObject, const Camera *camera) const;

        
        virtual ushort getIndex(Real value, const Mesh::MeshLodUsageList& meshLodUsageList) const = 0;

        
        virtual ushort getIndex(Real value, const Material::LodValueList& materialLodValueList) const = 0;

        
        virtual void sort(Mesh::MeshLodUsageList& meshLodUsageList) const = 0;

        
        virtual bool isSorted(const Mesh::LodValueList& values) const = 0;

        
        void assertSorted(const Mesh::LodValueList& values) const;

        
        const String& getName() const { return mName; }

    protected:
        
        static bool isSortedAscending(const Mesh::LodValueList& values);
        
        static bool isSortedDescending(const Mesh::LodValueList& values);

        
        static void sortAscending(Mesh::MeshLodUsageList& meshLodUsageList);
        
        static void sortDescending(Mesh::MeshLodUsageList& meshLodUsageList);

        
        static ushort getIndexAscending(Real value, const Mesh::MeshLodUsageList& meshLodUsageList);
        
        static ushort getIndexDescending(Real value, const Mesh::MeshLodUsageList& meshLodUsageList);

        
        static ushort getIndexAscending(Real value, const Material::LodValueList& materialLodValueList);
        
        static ushort getIndexDescending(Real value, const Material::LodValueList& materialLodValueList);

    };
	
	

} // namespace

#endif
